home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
TCL1
/
MIDI_MAN
/
CMIDIOUT.C
< prev
next >
Wrap
Text File
|
1992-03-07
|
6KB
|
163 lines
//--- CMIDIOutputPort.c ----------------------------------------------------------------
// Copyright ⌐ Paul Ferguson, 1990, 1991, 1992. All rights reserved.
//
// Superclass: CDataPort
// Subclasses: None
//
// Description:
// CMIDIOutputPort.c defines a MIDI Manager port object.
//
// For use with THINK C 5.0, the accompanying THINK Class Library (TCL), and MIDI
// Manager 2.0. Refer to the accompanying Microsoft Word document for complete
// details about MIDI Manager objects.
//
// If you have comments or questions about this code, you can reach me on
// CompuServe at 70441,3055.
//
//--------------------------------------------------------------------------------------
//---- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE ----
//--------------------------------------------------------------------------------------
// If you are not familiar with programming the Apple MIDI Manager, refer to the
// "MIDI Management Tools" Version 2.0, available from APDA. You MUST have the
// software (MIDI.H and the library) from this package in order to use these objects.
// It will not work without this.
//--------------------------------------------------------------------------------------
// REVISION HISTORY:
// August ??, 1990 - Original release (1.0).
// November 5, 1990 - Added checks for midiMgrVer to most methods.
// August 1991 - updated for THINK C 5.0 as version 2.0
//--------------------------------------------------------------------------------------
#include "CMIDIOutputPort.h" // This code's header file
extern OSType gSignature; // Used to register client
#define noClient ' ' // The UnClient
extern CMIDIClient * gMIDIClient;
OSErr CMIDIOutputPort::IMIDIOutputPort(StringPtr theName,
OSType thePortID,
Boolean theVisibleFlag,
CMIDITimePort * theTimePort,
long theOffset)
{
MIDIPortParams portParams; // MIDI Mgr Init data structure
register MIDIPortParams * portPPtr = &portParams;
portPPtr->portID = thePortID;
portPPtr->portType = midiPortTypeOutput;
if ( (theVisibleFlag == FALSE) && (itsVersion >= 0x0200) ) // Invisible output port, in 2.x
portPPtr->portType |= midiPortInvisible;
portPPtr->timeBase = theTimePort ? theTimePort->GetRefNum() : 0;
portPPtr->offsetTime = theOffset;
portPPtr->readHook = (Ptr) 0;
portPPtr->refCon = SetCurrentA5();
BlockMove(theName, portPPtr->name, theName[0]+1);
return IMIDIPort(portPPtr, 0);
}
OSErr CMIDIOutputPort::WritePacket(MIDIPacketPtr theMIDIPacket)
{
return itsVersion ? MIDIWritePacket(itsRefNum, theMIDIPacket) : ErrNoMIDI;
}
//--- CMIDIOutputPort::Write ----------------------------------------------
// Send a packet immediately without timestamp.
//-------------------------------------------------------------------------
OSErr CMIDIOutputPort::Write(char * theData, short theDataLen)
{
return DoMIDIWrite(theData, theDataLen, midiTimeStampCurrent, 0);
}
//--- CMIDIOutputPort::WriteTS --------------------------------------------
// Send a packet immediately with the user-supplied timestamp.
//-------------------------------------------------------------------------
OSErr CMIDIOutputPort::WriteTS(char * theData, short theDataLen, long theTimeStamp)
{
return DoMIDIWrite(theData, theDataLen, midiTimeStampValid, theTimeStamp);
}
//--- CMIDIOutputPort::DoMIDIWrite --------------------------------------------
// This local function does all the real work of sending MIDI data.
//
// This method is classified as 'private' in CMIDI.h. If you wish to call
// this method directly, simply change the header file.
//
// If you know your application is going to write a lot of short or fixed
// length packets, you may wish to override or modify this method to remove the
// BlockMove trap and multi-length packet logic overhead.
//
// It is called by CMIDIOutputPort::Write() and CMIDIOutputPort::WriteTS().
//-----------------------------------------------------------------------------
OSErr CMIDIOutputPort::DoMIDIWrite( char * theData,
short theDataLen,
unsigned char theFlags,
long theTimeStamp)
{
MIDIPacket midiPacket; // MIDI Manager packet to be transmitted
register MIDIPacketPtr midiPPtr = &midiPacket;
if (itsVersion == 0) return (ErrNoMIDI);
if (theDataLen < 250) // Handle short packets directly
{
midiPPtr->flags = theFlags | midiMsgType | midiNoCont;
midiPPtr->len = theDataLen + 6;
if (theFlags == midiTimeStampValid)
midiPPtr->tStamp = theTimeStamp;
BlockMove(theData, &(midiPPtr->data[0]), theDataLen);
return MIDIWritePacket(itsRefNum, &midiPacket);
}
else // Multiple packet send (more than 249 bytes)
{
register char * source = theData;
register short thisPacketLen;
OSErr err;
do
{
midiPPtr->flags = theFlags | midiMsgType; // Re-init each time
if (theFlags == midiTimeStampValid)
midiPPtr->tStamp = theTimeStamp;
thisPacketLen = (theDataLen < 249) ? theDataLen : 249;
BlockMove(source, &(midiPPtr->data[0]), thisPacketLen);// Data to write
/*
* Set the continuation bits field in the flags byte.
*/
theDataLen -= thisPacketLen;
if (source == theData) // the first piece of the message
{
if (theDataLen > 0) // Multiple writes required?
midiPPtr->flags |= midiStartCont; // Yes
else // Everything fits in one packet
midiPPtr->flags |= midiNoCont; // SHOULD NEVER SEE THIS CASE HERE!
}
else
{
if (theDataLen > 0) // a middle piece
midiPPtr->flags |= midiMidCont;
else // Last piece of the message
midiPPtr->flags |= midiEndCont;
}
midiPPtr->len = thisPacketLen + 6; // Set the packet length
err = MIDIWritePacket(itsRefNum, midiPPtr); // ÑÑÑ Call MIDI Manager
if (err) break;
// You may want to add more sophisticated error handling here. Also, if you are
// sending large packets like system exclusive messages, you may need to add a
// timing delay here so you don't overflow the output buffer or the device.
source += thisPacketLen; // Bump pointer
} while (theDataLen > 0); // Loop for next portion of data
return err; // Indicates last result
}
}
// end of CMIDIOutputPort.c